#!/usr/bin/python
#
# Vocab Tester - electronic flash cards
#
#   Alexei Czeskis 2011.02.09
#

import os
import csv
import random
import sys

class VocabTester:
  def __init__(self):
    self.vocab = {}
    self.troublesome = {}


  def addList(self, new_vocab):
    for k, v in new_vocab.iteritems():
      self.vocab[k] = v


  def addListFromCSV(self, vocab_file):
    rows_read = 0
    try:
      vocab_reader = csv.reader(open(vocab_file, 'r'))

      for row in vocab_reader:
        if (len(row) != 2):
          return -rows_read - 1 # negative means error, the number indicates row number. -1 because it's 0 indexed.
        else:
          k = row[0].strip()
          v = row[1].strip()
          self.vocab[k] = v
          rows_read += 1
    except (csv.Error, IOError):
      print 'Error in reading', vocab_file, 'Check your spelling.'

    return rows_read

  def addTroubleListFromCSV(self, vocab_file):
    rows_read = 0
    try:
      vocab_reader = csv.reader(open(vocab_file, 'r'))

      for row in vocab_reader:
        if (len(row) != 2):
          return -rows_read - 1 # negative means error, the number indicates row number. -1 because it's 0 indexed.
        else:
          k = row[0].strip()
          v = row[1].strip()
          self.troublesome[v] = k
          rows_read += 1
    except (csv.Error, IOError):
      print 'Error in reading', vocab_file, 'Check your spelling.'

    return rows_read


  def writeTroubleListToCSV(self, vocab_file):
    rows_written = 0
    try:
      vocab_writer = csv.writer(open(vocab_file,'w'), quoting=csv.QUOTE_NONE, escapechar='\\')
      for k, v in self.troublesome.iteritems():
        k = k.replace('"', '\"')
        v = v.replace('"', '\"')
        vocab_writer.writerow([v,k])
        rows_written += 1
      
    except csv.Error:
      print 'Error in writing', vocab_file, 'Check your spelling.'
      print 'k =', k, 'v =', v

    return rows_written


  def markAsTroublesome(self, word, direction):
    if( direction != 0 ):
      self.troublesome[word] = self.vocab[word]

    else:
      for k,v in self.vocab.iteritems():
        if( v == word):
          self.troublesome[word] = k
          break;


  def removeFromTroublesome(self, word, direction):
    if ( word in self.troublesome ):
      del self.troublesome[word]

    else:
      for k,v in self.troublesome.iteritems():
        if( v == word ):
          del self.troublesome[k]
          break;


  def emptyTroublesome(self):
    self.troublesome = {}


  def nextRandomWord(self, direction=0):
    rand_word = None
    definition = None

    words = self.vocab.keys()
    if ( len(words) > 0 ):
      rand_word = words[ int( random.random() * len(words) )]
      definition = self.vocab[rand_word]

      if( direction == 0 ):
        return [definition, rand_word]

    return [rand_word, definition]

  def nextRandomTroublesomeWord(self, direction):
    rand_word = None

    words = self.troublesome.keys()
    if ( len(words) > 0 ):
      rand_word = words[ int( random.random() * len(words) )]
      definition = self.troublesome[rand_word]

      if( direction != 0 ):
        return [definition, rand_word]

      return [rand_word, definition]


  def getTranslation(self, word, direction=0):

    translation = '[Translation not found]'

    if( direction == 0 ):
      for k, v in self.vocab.iteritems():
        if( v == word ):
          translation = k
          break;
    else:
      if (word in self.vocab):
        translation = self.vocab[word]


    return translation


def clearScreen():
  os.system( [ 'clear', 'cls' ][ os.name == 'nt' ] )
  

def switchTranlationDirection(direction):
  clearScreen()
  print 'Switch translation direction...'
  print '-' * 40 , "\n"
  print 'Current direction is' , 
  if( direction == 0 ):
    print '->'
  else:
    print '<-'
  print "\nSwitch translation direction? [y,n]"
  choice = raw_input('> ')
  choice = choice.lower()
  if( choice == 'y' ):
    return direction ^ 1
  else:
    return direction

def showRandomTroubleWord(vt, direction):
  while True:
    clearScreen()
    print 'Show a random trouble word...\t', len(vt.troublesome), 'total'
    print '-' * 50 , "\n"
    if ( len(vt.troublesome) < 1 ):
      print "No more trouble words"
      raw_input('Press Enter to return to main menu')
      break;
    else:
      next_word, definition = vt.nextRandomTroublesomeWord(direction)
      print "\t" , next_word
      raw_input("\nPress enter to see translation...")
      #translation = vt.getTranslation(next_word, direction)
      #if( translation == '[Translation not found]' ):
      #  translation = vt.getTranslation(next_word, direction ^ 1)
      print "\n\t", definition

      print "\n\nPress:"
      print "  [N] for next word"
      print "  [D] to remove word from trouble words"
      print "  [M] to return to main menu\n"
      choice = raw_input('> ')

      if( choice == 'n' ):
        pass
      elif ( choice == 'd' ):
        vt.removeFromTroublesome(next_word, direction)
      elif ( choice == 'm' ):
        break;
      else:
        pass #TODO: Fix this


def showRandomWord(vt, direction):
  while True:
    clearScreen()
    print 'Show a random word...'
    print '-' * 40 , "\n"
    next_word, definition = vt.nextRandomWord(direction)
    if( next_word is None ):
      print 'No words in list'
      raw_input('Press Enter to return to main menu...')
      break;
    else:
      print "\t" , next_word
      raw_input("\nPress enter to see translation...")
      print "\n\t", definition

      print "\n\nPress:"
      print "  [N] for next word"
      print "  [T] to add word to trouble words"
      print "  [M] to return to main menu\n"
      choice = raw_input('> ')

      if( choice == 'n' ):
        pass
      elif ( choice == 't' ):
        vt.markAsTroublesome(next_word, direction)
        pass
      elif ( choice == 'm' ):
        break;
      else:
        pass #TODO: Fix this


def getMainChoice():
  clearScreen()
  print 'Please make a choice:'
  print '  [A] Add vocab list'
  print '  [B] Add trouble vocab list'
  print '  [W] Show a random word'
  print '  [S] Switch translation direction'
  print '  [T] Show a random troublesome word'
  print '  [X] Write current trouble list'
  print "  [Q] Quit\n"
  choice =  raw_input('> ')
  return choice.lower()
  

def addVocabList(vt):
  clearScreen()
  print 'Adding vocab list...'
  print '-' * 40 , "\n"
  print 'Enter name of vocab file (CSV sytax)'
  vocab_file = raw_input('> ')
  rows_read = vt.addListFromCSV(vocab_file)

  if (rows_read == 0 ):
    print 'No rows read. Empty file?'
  elif (rows_read > 0):
    print 'Successfully read' , rows_read , 'words and tranlations.'
  else:
    print 'Error reading row' , -rows_read

  raw_input("\nPress enter to continue...")
  return vt


def addTroubleList(vt):
  clearScreen()
  print 'Adding trouble vocab list...'
  print '-' * 40 , "\n"
  print 'Enter name of trouble vocab file (CSV sytax)'
  vocab_file = raw_input('> ')
  rows_read = vt.addTroubleListFromCSV(vocab_file)
  if (rows_read == 0 ):
    print 'No rows read. Empty file?'
  elif (rows_read > 0):
    print 'Successfully read' , rows_read , 'words and tranlations.'
  else:
    print 'Error reading row' , -rows_read

  raw_input("\nPress enter to continue...")
  return vt


def writeTroubleList(vt):
  clearScreen()
  print 'Writing trouble vocab list to file...'
  print '-' * 60 , "\n"
  print 'Enter name of trouble vocab file (CSV sytax)'
  vocab_file = raw_input('> ')
  rows_written = vt.writeTroubleListToCSV(vocab_file)
  if (rows_written == 0 ):
    print 'No rows written. Empty list?'
  elif (rows_written> 0):
    print 'Successfully wrote' , rows_written, 'words and tranlations.'
  else:
    print 'Error writing row' , -rows_written

  raw_input("\nPress enter to continue...")

def main():
  vt = VocabTester()
  direction = 0;

  while True:
    choice = getMainChoice()

    if( choice == 'a' ):
      vt = addVocabList(vt)

    elif (choice == 'b'):
      vt = addTroubleList(vt)

    elif (choice == 'w'):
      showRandomWord(vt, direction)

    elif (choice == 's'):
      direction = switchTranlationDirection(direction)

    elif (choice == 't'):
      showRandomTroubleWord(vt, direction)

    elif (choice == 'x'):
      writeTroubleList(vt)

    elif (choice == 'q'):
      print 'Goodbye, Goodluck!'
      sys.exit(0)


if __name__ == "__main__":
    main()
